//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#if _MSC_VER > 1000
#pragma once
#endif

#if !defined(_WINHACK_H_)
#define _WINHACK_H_

#include <wintypes.h>
#include <debugdef.h>

//************************************************************************
//             API function for windows time
//************************************************************************
WINAPI_(void) GetSystemTime(
                   LPSYSTEMTIME lpSystemTime   // system time
                  );

WINAPI_(BOOL) SetSystemTime(
                   CONST SYSTEMTIME *lpSystemTime   // system time
                  );

WINAPI_(BOOL) FileTimeToSystemTime(
                   CONST FILETIME *lpFileTime,  // file time to convert
                   LPSYSTEMTIME lpSystemTime    // receives system time
                  );

WINAPI_(void) GetLocalTime(
                   LPSYSTEMTIME lpSystemTime   // system time
                  );

WINAPI_(BOOL) SetFileTime(
                   HANDLE hFile,
                   const FILETIME* lpCreationTime,
                   const FILETIME* lpLastAccessTime,
                   const FILETIME* lpLastWriteTime
                  );

//************************************************************************
//             API function for windows memory
//************************************************************************
#define PAGE_NOACCESS          0x01
#define PAGE_READONLY          0x02
#define PAGE_READWRITE         0x04
#define PAGE_WRITECOPY         0x08
#define PAGE_EXECUTE           0x10
#define PAGE_EXECUTE_READ      0x20
#define PAGE_EXECUTE_READWRITE 0x40
#define PAGE_EXECUTE_WRITECOPY 0x80
#define PAGE_GUARD             0x100
#define PAGE_NOCACHE           0x200
#define PAGE_WRITECOMBINE      0x400

WINAPI_(void*) CoTaskMemAlloc(ULONG);

WINAPI_(void*) CoTaskMemRealloc(void*, ULONG);

WINAPI_(void) CoTaskMemFree(void*);

WINAPI_(BSTR) SysAllocString(const OLECHAR*);

WINAPI_(BSTR) SysAllocStringLen(const OLECHAR*, UINT);

WINAPI_(INT)  SysReAllocString(BSTR *, const OLECHAR *);

WINAPI_(INT)  SysReAllocStringLen(BSTR *, const OLECHAR *, UINT);

WINAPI_(void) SysFreeString(BSTR);

WINAPI_(LPVOID) VirtualAlloc(
                   LPVOID lpAddress,        // region to reserve or commit
                   SIZE_T dwSize,           // size of region
                   DWORD flAllocationType,  // type of allocation
                   DWORD flProtect          // type of access protection
                  );

WINAPI_(BOOL) VirtualFree(
                   LPVOID lpAddress,   // address of region
                   SIZE_T dwSize,      // size of region
                   DWORD dwFreeType    // operation type
                  );

WINAPI_(BOOL) VirtualProtect(
                   LPVOID lpAddress,       // region of committed pages
                   SIZE_T dwSize,          // size of the region
                   DWORD flNewProtect,     // desired access protection
                   PDWORD lpflOldProtect   // old protection
                  );

WINAPI_(BOOL) VirtualProtectEx(
                   HANDLE hProcess,        // Handle to the process
                   LPVOID lpAddress,       // region of committed pages
                   SIZE_T dwSize,          // size of the region
                   DWORD flNewProtect,     // desired access protection
                   PDWORD lpflOldProtect   // old protection
                  );

WINAPI_(DWORD) VirtualQuery(
                   LPCVOID lpAddress,                   // address of region
                   PMEMORY_BASIC_INFORMATION lpBuffer,  // information buffer
                   SIZE_T dwLength                      // size of buffer
                  );

WINAPI_(VOID) CopyMemory(
                   PVoid Destination,   // copy destination
                   CONST VOID* Source,  // memory block
                   SIZE_T Length        // size of memory block
                  );

WINAPI_(BOOL) GetProcessMemoryInfo(
                    HANDLE Process,
                    PPROCESS_MEMORY_COUNTERS ppsmemCounters,
                    DWORD cb
                  );

WINAPI_(VOID) GlobalMemoryStatus(
                    LPMEMORYSTATUS lpBuffer
                  );

//************************************************************************
//             API function for windows process and thread
//************************************************************************
WINAPI_(BOOL) ExitProcess(
                   UINT uExitCode   // exit code for all threads
                  );

WINAPI_(HANDLE) GetCurrentProcess(void);

WINAPI_(DWORD) GetCurrentProcessId(void);

WINAPI_(BOOL) CreateProcessW(
                   LPCTSTR lpApplicationName,                 // name of executable module
                   LPTSTR lpCommandLine,                      // command line string
                   LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
                   LPSECURITY_ATTRIBUTES lpThreadAttributes,  // SD
                   BOOL bInheritHandles,                      // handle inheritance option
                   DWORD dwCreationFlags,                     // creation flags
                   LPVOID lpEnvironment,                      // new environment block
                   LPCTSTR lpCurrentDirectory,                // current directory name
                   LPSTARTUPINFO lpStartupInfo,               // startup information
                   LPPROCESS_INFORMATION lpProcessInformation // process information
                  );

WINAPI_(BOOL) TerminateProcess(
                   HANDLE hProcess, // handle to the process
                   UINT uExitCode   // exit code for the process
                  );

WINAPI_(HANDLE) OpenProcess(
                   DWORD dwDesiredAccess,  // access flag
                   BOOL bInheritHandle,    // handle inheritance option
                   DWORD dwProcessId       // process identifier
                  );

WINAPI_(BOOL) CloseHandle(
                   HANDLE hObject   // handle to object
                  );

WINAPI_(HANDLE) CreateThread(
                   LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
                   DWORD dwStackSize,                        // initial stack size
                   LPTHREAD_START_ROUTINE lpStartAddress,    // thread function
                   LPVOID lpParameter,                       // thread argument
                   DWORD dwCreationFlags,                    // creation option
                   LPDWORD lpThreadId                        // thread identifier
                  );

WINAPI_(HANDLE) CreateRemoteThread(
                   HANDLE hProcess,                          // handle to process
                   LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
                   DWORD dwStackSize,                        // initial stack size
                   LPTHREAD_START_ROUTINE lpStartAddress,    // thread function
                   LPVOID lpParameter,                       // thread argument
                   DWORD dwCreationFlags,                    // creation option
                   LPDWORD lpThreadId                        // thread identifier
                  );

WINAPI_(DWORD) ResumeThread(
                   HANDLE hThread   // handle to thread
                  );

WINAPI_(DWORD) SuspendThread(
                   HANDLE hThread   // handle to thread
                  );

WINAPI_(DWORD) GetCurrentThreadId(VOID);

WINAPI_(HANDLE) GetCurrentThread(VOID);

WINAPI_(BOOL) TerminateThread(
                   HANDLE hThread,    // handle to thread
                   DWORD dwExitCode   // exit code
                  );

WINAPI_(VOID) ExitThread(
                   DWORD dwExitCode   // exit code for this thread
                  );

WINAPI_(BOOL) SetThreadPriority(
                   HANDLE hThread, // handle to the thread
                   int nPriority   // thread priority level
                  );

WINAPI_(int) GetThreadPriority(
                   HANDLE hThread   // handle to thread
                  );

WINAPI_(BOOL) GetThreadTimes(
                   HANDLE hThread,             // handle to thread
                   LPFILETIME lpCreationTime,  // thread creation time
                   LPFILETIME lpExitTime,      // thread exit time
                   LPFILETIME lpKernelTime,    // thread kernel-mode time
                   LPFILETIME lpUserTime       // thread user-mode time
                  );

WINAPI_(BOOL) SetPriorityClass(
                   HANDLE hProcess,        // handle to process
                   DWORD dwPriorityClass   // priority class
                  );

WINAPI_(BOOL) GetExitCodeThread(
                   HANDLE hThread,      // handle to the thread
                   LPDWORD lpExitCode   // termination status
                  );

WINAPI_(HANDLE) OpenThread(
                   DWORD dwDesiredAccess,  // access right
                   BOOL bInheritHandle,    // handle inheritance option
                   DWORD dwThreadId        // thread identifier
                  );

WINAPI_(BOOL) SetPriorityClass(
                   HANDLE hProcess,        // handle to process
                   DWORD dwPriorityClass   // priority class
                  );

WINAPI_(DWORD) GetPriorityClass(
                   HANDLE hProcess   // handle to process
                  );

WINAPI_(BOOL) GetProcessTimes(
                   HANDLE hProcess,           // handle to process
                   LPFILETIME lpCreationTime, // process creation time
                   LPFILETIME lpExitTime,     // process exit time
                   LPFILETIME lpKernelTime,   // process kernel-mode time
                   LPFILETIME lpUserTime      // process user-mode time
                  );

WINAPI_(BOOL) GetExitCodeProcess(
                   HANDLE hProcess,     // handle to the process
                   LPDWORD lpExitCode   // termination status
                  );

WINAPI_(BOOL) GetExitCodeThread(
                   HANDLE hThread,      // handle to the thread
                   LPDWORD lpExitCode   // termination status
                  );

//************************************************************************
//             API function for windows synch machine
//************************************************************************
WINAPI_(DWORD) SignalObjectAndWait(
                   HANDLE hObjectToSignal,  // handle to object to signal
                   HANDLE hObjectToWaitOn,  // handle to object to watch
                   DWORD dwMilliseconds,    // time-out interval
                   BOOL bAlertable          // alertable option
                  );

WINAPI_(DWORD) WaitForSingleObjectEx(
                   HANDLE hHandle,        // handle to object
                   DWORD dwMilliseconds,  // time-out interval
                   BOOL bAlertable        // alertable option
                  );

WINAPI_(DWORD) WaitForMultipleObjects(
                   DWORD nCount,             // number of handles in array
                   CONST HANDLE *lpHandles,  // object-handle array
                   BOOL bWaitAll,            // wait option
                   DWORD dwMilliseconds      // time-out interval
                  );

WINAPI_(DWORD) WaitForSingleObject(
                   HANDLE hHandle,        // handle to object
                   DWORD dwMilliseconds   // time-out interval
                  );

#define STATUS_WAIT_0                       ((DWORD)0x00000000L)
#define WAIT_FAILED                         (DWORD)0xFFFFFFFF
#define WAIT_OBJECT_0                       ((STATUS_WAIT_0 ) + 0 )

WINAPI_(HANDLE) CreateMutexW(
                   LPSECURITY_ATTRIBUTES lpMutexAttributes,  // SD
                   BOOL bInitialOwner,                       // initial owner
                   LPCTSTR lpName                            // object name
                  );

WINAPI_(BOOL) ReleaseMutex(
                   HANDLE hMutex   // handle to mutex
                  );

WINAPI_(HANDLE) CreateEventW(
                   LPSECURITY_ATTRIBUTES lpEventAttributes, // SD
                   BOOL bManualReset,                       // reset type
                   BOOL bInitialState,                      // initial state
                   LPCTSTR lpName );                        // object name

WINAPI_(BOOL) ResetEvent(
                   HANDLE hEvent   // handle to event
                  );

WINAPI_(BOOL) PulseEvent(
                   HANDLE hEvent   // handle to event object
                  );

WINAPI_(BOOL) SetEvent(
                   HANDLE hEvent   // handle to event object
                  );

WINAPI_(VOID) InitializeCriticalSection(
                   LPRTL_CRITICAL_SECTION lpCriticalSection // critical section
                  );

WINAPI_(VOID) EnterCriticalSection(
                   LPRTL_CRITICAL_SECTION lpCriticalSection // critical section
                  );

WINAPI_(VOID) DeleteCriticalSection(
                   LPRTL_CRITICAL_SECTION lpCriticalSection  // critical section
                  );

WINAPI_(VOID) LeaveCriticalSection(
                   LPRTL_CRITICAL_SECTION lpCriticalSection  // critical section
                  );

WINAPI_(BOOL) TryEnterCriticalSection(
                   LPRTL_CRITICAL_SECTION lpCriticalSection // critical section
                  );

//************************************************************************
//             API function for windows registry
//************************************************************************
//WINAPI_(LONG) RegCreateKeyExW(
//                    HKEY hKey,                                  // handle to open key
//                    LPCTSTR lpSubKey,                           // subkey name
//                    DWORD Reserved,                             // reserved
//                    LPTSTR lpClass,                             // class string
//                    DWORD dwOptions,                            // special options
//                    REGSAM samDesired,                          // desired security access
//                    LPSECURITY_ATTRIBUTES lpSecurityAttributes, // inheritance
//                    PHKEY phkResult,                            // key handle
//                    LPDWORD lpdwDisposition                     // disposition value buffer
//                  );
//
//WINAPI_(LONG) RegSetValueExW(
//                    HKEY hKey,           // handle to key
//                    LPCTSTR lpValueName, // value name
//                    DWORD Reserved,      // reserved
//                    DWORD dwType,        // value type
//                    CONST BYTE *lpData,  // value data
//                    DWORD cbData         // size of value data
//                  );
//
//WINAPI_(LONG) RegCloseKey(
//                    HKEY hKey   // handle to key to close
//                  );
//
//WINAPI_(LONG) RegOpenKeyExW(
//                   HKEY hKey,         // handle to open key
//                   LPCTSTR lpSubKey,  // subkey name
//                   DWORD ulOptions,   // reserved
//                   REGSAM samDesired, // security access mask
//                   PHKEY phkResult    // handle to open key
//                  );
//
//WINAPI_(LONG) RegDeleteKeyW(
//                   HKEY hKey,         // handle to open key
//                   LPCTSTR lpSubKey   // subkey name
//                  );
//
//WINOLEAPI StringFromCLSID(
//                   REFCLSID rclsid, //CLSID to be converted
//                   LPOLESTR * ppsz  //Address of output variable that receives a
//                                     // pointer to the resulting string
//                  );
//
//WINAPI_(LONG) RegOpenKeyExW(
//                   HKEY hKey,
//                   LPCWSTR lpSubKey,
//                   DWORD ulOptions,
//                   REGSAM samDesired,
//                   PHKEY phkResult
//                  );
//
//#define RegOpenKeyEx  RegOpenKeyExW
//
//WINAPI_(LONG) RegCreateKeyEx(
//                   HKEY hKey,
//                   LPCWSTR lpSubKey,
//                   DWORD Reserved,
//                   LPWSTR lpClass,
//                   DWORD dwOptions,
//                   REGSAM samDesired,
//                   LPSECURITY_ATTRIBUTES lpSecurityAttributes,
//                   PHKEY phkResult,
//                   LPDWORD lpdwDisposition
//                  );
//
//WINAPI_(LONG) RegSetValueExW(
//                   HKEY hKey,
//                   LPCWSTR lpValueName,
//                   DWORD Reserved,
//                   DWORD dwType,
//                   const BYTE *lpData,
//                   DWORD cbData
//                  );
//
//#define RegSetValueEx  RegSetValueExW
//
//WINAPI_(LONG) RegEnumKeyExW(
//                   HKEY hKey,
//                   DWORD dwIndex,
//                   LPWSTR lpName,
//                   LPDWORD lpcbName,
//                   LPDWORD lpReserved,
//                   LPWSTR lpClass,
//                   LPDWORD lpcbClass,
//                   PFILETIME lpftLastWriteTime
//                  );
//
//#define RegEnumKeyEx  RegEnumKeyExW

//************************************************************************
//             API function for windows COM
//************************************************************************
//WINOLEAPI_(INT32) CoRegisterClassObject(
//                   REFCLSID rclsid,     //Class identifier (CLSID) to be registered
//                   IUnknown * pUnk,     //Pointer to the class object
//                   DWORD dwClsContext,  //Context for running executable code
//                   DWORD flags,         //How to connect to the class object
//                   LPDWORD  lpdwRegister
//                                         //Pointer to the value returned
//                  );
//
//WINOLEAPI CoRevokeClassObject(
//                   DWORD dwRegister  //Token on class object
//                  );
//
//WINOLEAPI CoCreateObjectEx(
//  REFCLSID rclsid,             //CLSID of the object to be created
//  IUnknown *punkOuter,         //If part of an aggregate, the
//                               // controlling IUnknown
//  DWORD dwClsCtx,              //CLSCTX values
//  COSERVERINFO *pServerInfo,   //Machine on which the object is to
//                               // be instantiated
//  ULONG cmq,                   //Number of MULTI_QI structures in
//                               // pResults
//  MULTI_QI *pResults           //Array of MULTI_QI structures
//);
//
//WINOLEAPI CoGetClassObject(
//                   REFCLSID rclsid,  //CLSID associated with the class object
//                   DWORD dwClsContext,//Context for running executable code
//                   COSERVERINFO * pServerInfo,//Pointer to machine on which the object is to
//                                     // be instantiated
//                   REFIID riid,      //Reference to the identifier of the interface
//                   LPVOID * ppv      //Address of output variable that receives the
//                                     // interface pointer requested in riid
//                  );
//
//WINOLEAPI CoCreateObject(
//  REFCLSID rclsid,     //Class identifier (CLSID) of the object
//  LPUNKNOWN pUnkOuter, //Pointer to controlling IUnknown
//  DWORD dwClsContext,  //Context for running executable code
//  REFIID riid,         //Reference to the identifier of the interface
//  LPVOID * ppv         //Address of output variable that receives
//                       // the interface pointer requested in riid
//);
//
//WINOLEAPI CoInitializeEx(
//  void * pvReserved,  //Reserved
//  DWORD dwCoInit      //COINIT value
//);
//
//WINOLEAPI CoInitialize(
//  LPVOID pvReserved  //Reserved; must be NULL
//);
//
//WINOLEAPI_(VOID) CoUninitialize( );
//
//WINOLEAPI_(VOID) CoFreeUnusedLibraries();
//
//WINOLEAPI CoCreateFreeThreadedMarshaler(
//  LPUNKNOWN punkOuter,        //Pointer to object aggregating the
//                              // marshaler object
//  LPUNKNOWN * ppunkMarshaler  //Address of output variable that
//                              // receives the IUnknown interface
//                              // pointer to the marshaler object
//);
//WINAPI_(BOOL) DisableThreadLibraryCalls(
//  HMODULE hModule  // handle to DLL module
//);

//************************************************************************
//             API function for windows Messages
//************************************************************************
WINAPI_(VOID) PostQuitMessage(
                    int nExitCode   // exit code
                  );

WINAPI_(BOOL) TranslateMessage(
                   const MSG *lpMsg   // message information
                  );

WINAPI_(BOOL) PostThreadMessageW(
  DWORD idThread, // thread identifier
  UINT Msg,       // message
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);

#define PostThreadMessage  PostThreadMessageW

WINAPI_(LRESULT) DispatchMessageW(
  CONST MSG *lpmsg   // message information
);

#define DispatchMessage  DispatchMessageW

WINAPI_(BOOL) GetMessageW(
    LPMSG lpMsg,
    HWND hWnd ,
    UINT wMsgFilterMin,
    UINT wMsgFilterMax);

#define GetMessage  GetMessageW

//************************************************************************
//             API function for windows modules
//************************************************************************
WINAPI_(HANDLE) CreateToolhelp32Snapshot(
                   DWORD dwFlags,
                   DWORD th32ProcessID
                  );

WINAPI_(BOOL) Module32First(
                   HANDLE hSnapshot,
                   LPMODULEENTRY32 lpme
                  );

WINAPI_(BOOL) Module32Next(
                   HANDLE hSnapshot,
                   LPMODULEENTRY32 lpme
                  );

WINAPI_(BOOL) GetModuleInformation(
                   HANDLE hProcess,         // handle to process
                   HMODULE hModule,         // handle to module
                   LPMODULEINFO lpmodinfo,  // information buffer
                   DWORD cb                 // size of buffer
                  );

WINAPI_(FARPROC) GetProcAddress(
                   HMODULE hModule,    // handle to DLL module
                   LPCSTR lpProcName   // function name
                  );

WINAPI_(HMODULE) LoadLibraryW(
                   LPCWSTR lpFileName
                  );

WINAPI_(HANDLE) LoadLibraryExW(
                   LPCTSTR lpFileName,  // file name of module
                   HANDLE hFile,           // reserved, must be NULL
                   DWORD dwFlags           // entry-point execution option
                  );

WINAPI_(BOOL) FreeLibrary(
                   HMODULE hModule
                  );

WINAPI_(HMODULE ) GetModuleHandleW(
                   LPCTSTR lpModuleName   // module name
                  );

//************************************************************************
//             API function for File I/O
//************************************************************************
WINAPI_(HANDLE) CreateFileA(
                   LPCSTR lpFileName,
                   DWORD dwDesiredAccess,
                   DWORD dwShareMode,
                   LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                   DWORD dwCreationDisposition,
                   DWORD dwFlagsAndAttributes,
                   HANDLE hTemplateFile
                  );

WINAPI_(HANDLE) CreateFileW(
                   LPCWSTR lpFileName,
                   DWORD dwDesiredAccess,
                   DWORD dwShareMode,
                   LPSECURITY_ATTRIBUTES lpSecurityAttributes,
                   DWORD dwCreationDisposition,
                   DWORD dwFlagsAndAttributes,
                   HANDLE hTemplateFile
                  );

WINAPI_(BOOL) LockFileEx(
                   HANDLE hFile,
                   DWORD dwFlags,
                   DWORD dwReserved,
                   DWORD nNumberOfBytesToLockLow,
                   DWORD nNumberOfBytesToLockHigh,
                   LPOVERLAPPED lpOverlapped
                  );

#define LOCKFILE_FAIL_IMMEDIATELY   0x00000001
#define LOCKFILE_EXCLUSIVE_LOCK     0x00000002

WINAPI_(BOOL) UnlockFileEx(
                   HANDLE hFile,
                   DWORD dwReserved,
                   DWORD nNumberOfBytesToUnlockLow,
                   DWORD nNumberOfBytesToUnlockHigh,
                   LPOVERLAPPED lpOverlapped
                  );

WINAPI_(BOOL) CancelIo(
                   HANDLE hFile
                  );

#define ERROR_IO_PENDING                 997L

//
// File creation flags must start at the high end since they
// are combined with the attributes
//

#define FILE_FLAG_WRITE_THROUGH         0x80000000
#define FILE_FLAG_OVERLAPPED            0x40000000
#define FILE_FLAG_NO_BUFFERING          0x20000000
#define FILE_FLAG_RANDOM_ACCESS         0x10000000
#define FILE_FLAG_SEQUENTIAL_SCAN       0x08000000
#define FILE_FLAG_DELETE_ON_CLOSE       0x04000000
#define FILE_FLAG_BACKUP_SEMANTICS      0x02000000
#define FILE_FLAG_POSIX_SEMANTICS       0x01000000
#define FILE_FLAG_OPEN_REPARSE_POINT    0x00200000
#define FILE_FLAG_OPEN_NO_RECALL        0x00100000

#define CREATE_NEW          1
#define CREATE_ALWAYS       2
#define OPEN_EXISTING       3
#define OPEN_ALWAYS         4
#define TRUNCATE_EXISTING   5

#define GENERIC_READ                     (0x80000000L)
#define GENERIC_WRITE                    (0x40000000L)
#define GENERIC_EXECUTE                  (0x20000000L)
#define GENERIC_ALL                      (0x10000000L)

//
// Define access rights to files and directories
//
#define FILE_SHARE_READ                 0x00000001
#define FILE_SHARE_WRITE                0x00000002
#define FILE_SHARE_DELETE               0x00000004
#define FILE_ATTRIBUTE_READONLY             0x00000001
#define FILE_ATTRIBUTE_HIDDEN               0x00000002
#define FILE_ATTRIBUTE_SYSTEM               0x00000004
#define FILE_ATTRIBUTE_DIRECTORY            0x00000010
#define FILE_ATTRIBUTE_ARCHIVE              0x00000020
#define FILE_ATTRIBUTE_ENCRYPTED            0x00000040
#define FILE_ATTRIBUTE_NORMAL               0x00000080
#define FILE_ATTRIBUTE_TEMPORARY            0x00000100
#define FILE_ATTRIBUTE_SPARSE_FILE          0x00000200
#define FILE_ATTRIBUTE_REPARSE_POINT        0x00000400
#define FILE_ATTRIBUTE_COMPRESSED           0x00000800
#define FILE_ATTRIBUTE_OFFLINE              0x00001000
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  0x00002000
#define FILE_NOTIFY_CHANGE_FILE_NAME    0x00000001
#define FILE_NOTIFY_CHANGE_DIR_NAME     0x00000002
#define FILE_NOTIFY_CHANGE_ATTRIBUTES   0x00000004
#define FILE_NOTIFY_CHANGE_SIZE         0x00000008
#define FILE_NOTIFY_CHANGE_LAST_WRITE   0x00000010
#define FILE_NOTIFY_CHANGE_LAST_ACCESS  0x00000020
#define FILE_NOTIFY_CHANGE_CREATION     0x00000040
#define FILE_NOTIFY_CHANGE_SECURITY     0x00000100
#define FILE_ACTION_ADDED                   0x00000001
#define FILE_ACTION_REMOVED                 0x00000002
#define FILE_ACTION_MODIFIED                0x00000003
#define FILE_ACTION_RENAMED_OLD_NAME        0x00000004
#define FILE_ACTION_RENAMED_NEW_NAME        0x00000005
#define MAILSLOT_NO_MESSAGE             ((DWORD)-1)
#define MAILSLOT_WAIT_FOREVER           ((DWORD)-1)
#define FILE_CASE_SENSITIVE_SEARCH      0x00000001
#define FILE_CASE_PRESERVED_NAMES       0x00000002
#define FILE_UNICODE_ON_DISK            0x00000004
#define FILE_PERSISTENT_ACLS            0x00000008
#define FILE_FILE_COMPRESSION           0x00000010
#define FILE_VOLUME_QUOTAS              0x00000020
#define FILE_SUPPORTS_SPARSE_FILES      0x00000040
#define FILE_SUPPORTS_REPARSE_POINTS    0x00000080
#define FILE_SUPPORTS_REMOTE_STORAGE    0x00000100
#define FILE_VOLUME_IS_COMPRESSED       0x00008000
#define FILE_SUPPORTS_OBJECT_IDS        0x00010000
#define FILE_SUPPORTS_ENCRYPTION        0x00020000

WINAPI_(DWORD) GetTempPathA(
                    DWORD nBufferLength,
                    LPSTR lpBuffer
                   );
WINAPI_(DWORD) GetTempPathW(
                    DWORD nBufferLength,
                    LPWSTR lpBuffer
                   );

WINAPI_(UINT) GetTempFileNameA(
                    LPCSTR lpPathName,
                    LPCSTR lpPrefixString,
                    UINT uUnique,
                    LPSTR lpTempFileName
                   );
WINAPI_(UINT) GetTempFileNameW(
                    LPCWSTR lpPathName,
                    LPCWSTR lpPrefixString,
                    UINT uUnique,
                    LPWSTR lpTempFileName
                   );

WINAPI_(BOOL) DeleteFileA(
                    LPCSTR lpFileName
                   );

WINAPI_(BOOL) DeleteFileW(
                    LPCWSTR lpFileName
                   );

WINAPI_(DWORD) GetFileAttributesW(
                    PCWSTR lpFileName
                   );

WINAPI_(BOOL) SetFileAttributesW(
                    PCWSTR lpFileName,
                    DWORD dwFileAttributes
                   );

WINAPI_(DWORD) GetFileSize(
                    HANDLE hFile,
                    LPDWORD lpFileSizeHigh
                   );

WINAPI_(BOOL) ReadFile(
                    HANDLE hFile,
                    LPVOID lpBuffer,
                    DWORD nNumberOfBytesToRead,
                    LPDWORD lpNumberOfBytesRead,
                    LPOVERLAPPED lpOverlapped
                   );

WINAPI_(DWORD) SetFilePointer(
                    HANDLE hFile,
                    LONG lDistanceToMove,
                    PLONG lpDistanceToMoveHigh,
                    DWORD dwMoveMethod
                   );

WINAPI_(BOOL) SetEndOfFile(
                    HANDLE hFile
                   );

WINAPI_(BOOL) WriteFile(
                    HANDLE hFile,
                    const void * lpBuffer,
                    DWORD nNumberOfBytesToWrite,
                    DWORD* lpNumberOfBytesWritten,
                    OVERLAPPED* lpOverlapped
                   );

WINAPI_(BOOL) GetFileTime(
                    HANDLE hFile,
                    LPFILETIME lpCreationTime,
                    LPFILETIME lpLastAccessTime,
                    LPFILETIME lpLastWriteTime
                   );

WINAPI_(DWORD) GetCurrentDirectoryW(
                    DWORD nBufferLength,
                    LPWSTR lpBuffer
                   );

WINAPI_(BOOL) MoveFileW(
                    LPCWSTR lpExistingFileName,
                    LPCWSTR lpNewFileName
                   );

WINAPI_(BOOL) CreateDirectoryW(
                    LPCWSTR lpPathName,
                    LPSECURITY_ATTRIBUTES lpSecurityAttributes
                   );

WINAPI_(BOOL) RemoveDirectoryW(
                    PCWSTR lpPathName
                   );

WINAPI_(HANDLE) FindFirstFileW(
                    wchar_t* lpFileName,
                    LPWIN32_FIND_DATAW lpFindFileData
                   );

WINAPI_(BOOL) FindNextFileW(
                    HANDLE hFindFile,
                    LPWIN32_FIND_DATAW lpFindFileData
                   );

WINAPI_(BOOL) FindClose(
                    HANDLE hFindFile
                   );

WINAPI_(BOOL) FlushFileBuffers(
                    HANDLE hFile
                   );

//************************************************************************
//             API function for thread local storage
//************************************************************************
WINAPI_(DWORD) TlsAlloc(
                   VOID
                  );

#ifndef TLS_OUT_OF_INDEXES
#define TLS_OUT_OF_INDEXES (DWORD)0xFFFFFFFF
#endif

WINAPI_(LPVOID) TlsGetValue(
                   DWORD dwTlsIndex
                  );

WINAPI_(BOOL) TlsSetValue(
                   DWORD dwTlsIndex,
                   LPVOID lpTlsValue
                  );

WINAPI_(BOOL) TlsFree(
                   DWORD dwTlsIndex
                  );

//************************************************************************
//             API function for debugging functions
//************************************************************************

//
// The LDT_ENTRY structure describes an entry in the descriptor table.
// This structure is valid only on x86-based systems.
//
typedef struct _LDT_ENTRY {
    WORD    LimitLow;
    WORD    BaseLow;
    union {
        struct {
            BYTE    BaseMid;
            BYTE    Flags1;     // Declare as bytes to avoid alignment
            BYTE    Flags2;     // Problems.
            BYTE    BaseHi;
        } Bytes;
        struct {
            DWORD   BaseMid : 8;
            DWORD   Type : 5;
            DWORD   Dpl : 2;
            DWORD   Pres : 1;
            DWORD   LimitHi : 4;
            DWORD   Sys : 1;
            DWORD   Reserved_0 : 1;
            DWORD   Default_Big : 1;
            DWORD   Granularity : 1;
            DWORD   BaseHi : 8;
        } Bits;
    } HighWord;
} LDT_ENTRY, *PLDT_ENTRY, *LPLDT_ENTRY;

//
// Thread information block
//
typedef struct _EXCEPTION_REGISTRATION_RECORD
{
    struct _EXCEPTION_REGISTRATION_RECORD * pNext;
    FARPROC pfnHandler;
} EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;

typedef struct _NT_TIB {
    struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
    PVOID StackBase;
    PVOID StackLimit;
    PVOID SubSystemTib;
    union {
        PVOID FiberData;
        DWORD Version;
    };
    PVOID ArbitraryUserPointer;
    struct _NT_TIB *Self;
} NT_TIB;
typedef NT_TIB *PNT_TIB;

WINAPI_(BOOL) DebugActiveProcess(
                    DWORD dwProcessId);

WINAPI_(BOOL) DebugActiveProcessStop(
                    DWORD dwProcessId);

WINAPI_(BOOL) WriteProcessMemory(
                    HANDLE hProcess,
                    LPVOID lpBaseAddress,
                    LPCVOID lpBuffer,
                    SIZE_T nSize,
                    SIZE_T * lpNumberOfBytesWritten);

WINAPI_(BOOL) ReadProcessMemory(
                    HANDLE hProcess,
                    LPCVOID lpBaseAddress,
                    LPVOID lpBuffer,
                    SIZE_T nSize,
                    SIZE_T * lpNumberOfBytesRead);

WINAPI_(BOOL) SetThreadContext(
                    HANDLE hThread,
                    CONST Context *lpContext);

WINAPI_(BOOL) GetThreadContext(
                    HANDLE hThread,
                    Context * lpContext);

WINAPI_(BOOL) WaitForDebugEvent(
                    LPDEBUG_EVENT lpDebugEvent,
                    DWORD dwMilliseconds);

WINAPI_(BOOL) ContinueDebugEvent(
                    DWORD dwProcessId,
                    DWORD dwThreadId,
                    DWORD dwContinueStatus);

WINAPI_(BOOL) GetThreadSelectorEntry(
                    HANDLE hThread,
                    DWORD dwSelector,
                    LPLDT_ENTRY lpSelectorEntry);

//************************************************************************
//               other API function for windows
//************************************************************************
WINAPI_(VOID) GetSystemInfo(
                   LPSYSTEM_INFO lpSystemInfo  // system information
                  );

WINAPI_(DWORD) GetLastError(VOID);

WINAPI_(DWORD) GetTickCount(VOID);

WINAPI_(void) Sleep(
                   DWORD dwMilliseconds   // sleep time
                  );

WINAPI_(DWORD) GetModuleFileNameW(
                   HMODULE hModule,
                   wchar_t* lpFilename,
                   DWORD nSize
                  );

WINAPI_(PWSTR) GetCommandLineW(void);

WINAPI_(int) MessageBoxW(
  HWND hWnd,          // handle to owner window
  LPCTSTR lpText,     // text in message box
  LPCTSTR lpCaption,  // message box title
  UINT uType          // message box style
);

WINAPI_(LPSTR) lstrcpyA(
                LPSTR lpString1,
                LPCSTR lpString2
               );

WINAPI_(LPWSTR) lstrcpyW(
                LPWSTR lpString1,
                LPCWSTR lpString2
               );

WINAPI_(LPSTR) lstrcatA(
                LPSTR lpString1,
                LPCSTR lpString2
               );

WINAPI_(LPWSTR) lstrcatW(
                LPWSTR lpString1,
                LPCWSTR lpString2
               );

WINAPI_(int) lstrlenA(
                LPCSTR lpString
               );

WINAPI_(int) lstrlenW(
                LPCWSTR lpString
               );

WINAPI_(BOOL) PathRemoveFileSpecW(
                LPCWSTR pszPath
               );

WINAPI_(DWORD) GetCurrentDirectoryW(
                DWORD nBufferLength,
                LPWSTR lpBuffer
               );

WINAPI_(HRSRC) FindResourceW(
    HMODULE hModule,
    LPCWSTR lpName,
    LPCWSTR lpType
    );

WINAPI_(DWORD) SizeofResource(
    HMODULE hModule,
    HRSRC hResInfo
    );

WINAPI_(HGLOBAL) LoadResource(
    HMODULE hModule,
    HRSRC hResInfo
    );

WINAPI_(LPVOID) LockResource(
        HGLOBAL hResData
        );

WINAPI_(DWORD) GetTimeZoneInformation(
    LPTIME_ZONE_INFORMATION lpTimeZoneInformation
    );

WINAPI_(BOOL) SetTimeZoneInformation(
    const TIME_ZONE_INFORMATION* lpTimeZoneInformation
    );

WINAPI_(BOOL) QueryPerformanceFrequency(
          LARGE_INTEGER *lpFrequency
);

WINAPI_(BOOL) QueryPerformanceCounter(
          LARGE_INTEGER *lpFrequency
);

WINAPI_(HANDLE) CreateFileMappingW(
  HANDLE hFile,
  LPSECURITY_ATTRIBUTES lpAttributes,
  DWORD flProtect,
  DWORD dwMaximumSizeHigh,
  DWORD dwMaximumSizeLow,
  LPCTSTR lpName
);

WINAPI_(HANDLE) OpenFileMappingW(
  DWORD dwDesiredAccess,
  BOOL bInheritHandle,
  LPCTSTR lpName
);

WINAPI_(LPVOID) MapViewOfFile(
  HANDLE hFileMappingObject,
  DWORD dwDesiredAccess,
  DWORD dwFileOffsetHigh,
  DWORD dwFileOffsetLow,
  SIZE_T dwNumberOfBytesToMap
);

WINAPI_(BOOL) UnmapViewOfFile(
  LPCVOID lpBaseAddress
);

#define STANDARD_RIGHTS_REQUIRED         (0x000F0000L)
#define SYNCHRONIZE                      (0x00100000L)
#define MUTANT_QUERY_STATE      0x0001

#define MUTANT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|\
                          MUTANT_QUERY_STATE)

#define MUTEX_ALL_ACCESS MUTANT_ALL_ACCESS
#define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)

WINAPI_(HANDLE) OpenEventW(
  DWORD dwDesiredAccess,
  BOOL bInheritHandle,
  LPCTSTR lpName
);

WINAPI_(HANDLE) CreateMutexW(
                   LPSECURITY_ATTRIBUTES lpMutexAttributes,  // SD
                   BOOL bInitialOwner,                       // initial owner
                   LPCTSTR lpName                            // object name
                  );

WINAPI_(HANDLE) OpenMutexW(
                   DWORD dwDesiredAccess,
                   BOOL bInheritHandle,
                   LPCTSTR lpName
                  );

WINAPI_(LRESULT) SendMessageW(
    HWND hWnd,
    UINT Msg,
    WPARAM wParam,
    LPARAM lParam
);

WINAPI_(HWND) FindWindowA(
    LPCTSTR lpClassName,
    LPCTSTR lpWindowName
);

WINAPI_(BOOL) GetDiskFreeSpaceExW(
    LPCTSTR lpDirectoryName,
    PULARGE_INTEGER lpFreeBytesAvailable,
    PULARGE_INTEGER lpTotalNumberOfBytes,
    PULARGE_INTEGER lpTotalNumberOfFreeBytes
);

WINAPI_(BOOL) FlushInstructionCache(
    HANDLE hProcess,
    LPCVOID lpBaseAddress,
    SIZE_T dwSize
);

#endif
